# -*- coding: utf-8 -*-
# @Time    : 2021/11/1 下午5:32
# @Author  : hanyunxi
# @description   :
import pandas as pd #To work with dataset
import numpy as np #Math library
# 静态
import seaborn as sns #Graph library that use matplot in background
import matplotlib.pyplot as plt #to plot some parameters in seaborn
# it's a library that we work with plotly
# 动态
import plotly.offline as py
# py.init_notebook_mode(connected=True) # this code, allow us to work with offline plotly version
import plotly.graph_objs as go # it's like "plt" of matplot
import plotly.tools as tls # It's useful to we get some tools of plotly
import warnings # This library will be used to ignore some warnings
from collections import Counter # To do counter of some features
import plotly.figure_factory as ff
from plotly import tools

def read_file():
    filepath = "../file/german_credit_data-1.csv"
    df = pd.read_csv(filepath)
    return df

# 数据清洗
def data_clean():
    df = read_file()
    # 搜索缺失值、数据类型以及已知数据的形
    print(df.info())
    # Looking unique values
    # print(df.nunique())
    # looking the data
    # print(df.head(5))

# 查看目标变量及其分布
def getDataByRisk():
    df = read_file()
    df_new = df.groupby('Risk')['Risk'].count()
    # 方法 1
    # 设置 柱状图 大小
    # fig,axes = plt.subplots(1,1,figsize=(16,9))
    # ax = sns.barplot(x=df_new.index,y=df_new.values,palette="tab20c")
    # ax.bar_label(ax.containers[0])
    # plt.xticks(rotation=90)
    # plt.title("Target variable distribution")
    # plt.show()

    # 方法2  基于 web页面 渲染
    trace = go.Bar(x=df_new.index,y=df_new.values,name="credit risk rate")
    data = [trace]
    layout = go.Layout(xaxis=dict(title = "Risk Variable"),yaxis=dict(title="Count"),title="Target variable distribution")
    fig = go.Figure(data=data,layout=layout)
    py.iplot(fig,filename="grouped-bar")

# 显示 不同年龄 信用风险 分布情况
def getTargetVariableDistribution():
    df_new = read_file()
    df_good = df_new.loc[df_new['Risk'] == 'good']['Age'].values.tolist()
    df_bad = df_new.loc[df_new['Risk'] == 'bad']['Age'].values.tolist()
    # df_new[df_new['Risk'] == 'good'][:,'Age']
    print("数据类型:",type(df_new[df_new['Risk'] == 'good']))
    df_age = df_new['Age'].values.tolist()
    df_dict = {0:df_good,1:df_bad,2:df_age}
    titles = {0:"Good Credit",1:"Bad Credit",2:"Overall Age"}

    fig = tls.make_subplots(rows=2,cols=2,specs=[[{}, {}], [{'colspan': 2}, None]],subplot_titles=('Good','Bad', 'General Distribuition'))
    # plot  封装
    for index in range(3):
        trace = go.Histogram(x=df_dict[index],histnorm="probability",name=titles[index])
        # Creating the grid
        # setting the figs  (1,1) (1,2) (2,1)
        if index <= 1:
            fig.append_trace(trace, 1, 1+index)
        else:
            fig.append_trace(trace,2,1)
        # 最后一次  渲染数据 在一起
        if index == 2:
            fig['layout'].update(showlegend=True, title="Age Distribuition", bargap=0.05)
            py.iplot(fig, filename="custom-sized-subplot-with-subplot-titles")

# 将按风险查看房屋自有和租金的分布
def getHouseByRisk():
    df = read_file()
    df_good = df[df["Risk"] == 'good']["Housing"]
    df_bad = df[df["Risk"] == 'bad']["Housing"]
    # 数据 封装
    titles = {0:"Good credit",1:"Bad Credit"}
    df_dict = {0:df_good,1:df_bad}
    data = []
    for index in range(2):
        # print(df_dict[index].value_counts().index.values)
        # print(df_dict[index].value_counts().values)
        trace = go.Bar(x=df_dict[index].value_counts().index.values,y=df_dict[index].value_counts().values,name=titles[index])
        data.append(trace)
    layout = go.Layout(title="Housing Distribuition")
    fig = go.Figure(data=data,layout=layout)
    py.iplot(fig,filename="Housing-Grouped")

# 住房信贷额度分布
def getCreditAmountByHousing():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']

    fig = {
        "data":[
            {
                "type": 'violin',
                "x": df_good['Housing'],
                "y": df_good['Credit amount'],
                "legendgroup": 'Good Credit',
                "scalegroup": 'No',
                "name": 'Good Credit',
                "side": 'negative',
                "box": {
                    "visible": True
                },
                "meanline": {
                    "visible": True
                },
                "line": {
                    "color": 'blue'
                }
            },
            {
                "type":"violin",
                "x":df_bad['Housing'],
                "y":df_bad['Credit amount'],
                "legendgroup":"Good Credit",
                "scalegroup":"no",
                "name":"Bad Credit",
                "side":"negative",
                "box":{
                    "visible":True
                },
                "meanline":{
                    "visible":True
                },
                "line":{
                    "color":"green"
                }
            }
        ],
        "layout":{
            "yaxis":{
                "zeroline":False
            },
            "violingap":0,
            "violinmode":"overlay"
        }
    }
    py.iplot(fig,filename="violin/split",validate=False)

# 按性别看风险差异
def getRiskDataBySex():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']

    df_dict = {0:df_good,1:df_bad}
    titles = {0:"Good Credit by sex",1:"Bad Credit by sex"}
    data = []
    for index in range(4):
        if index <= 1:
            trace = go.Bar(x=df_dict[index]["Sex"].value_counts().index.values,y=df_dict[index]['Sex'].value_counts().values,name=titles[index])
        else:
            trace = go.Box(x=df_dict[index-2]['Sex'],y=df_dict[index-2]['Credit amount'],name=titles[index-2])
        data.append(trace)
    # 绘图  显示  1  行 2  列
    fig = tls.make_subplots(rows=1, cols=2,subplot_titles=('Sex Count', 'Credit Amount by Sex'))
    for index in range(len(data)):
        if index <= 1:
            fig.append_trace(data[index],1,1)
        else:
            fig.append_trace(data[index],1,2)
    fig['layout'].update(height=520,width=1000,title="Sex Distribuition",boxmode="group")
    py.iplot(fig,filename="SexDistribuition")

# 如何在不同的地方设置箱线图？如何对两个图形使用相同的图例？
# 创建年龄类别并查看信用金额按风险的分布.
# 1. Distribuition
def getRiskDataDistribuitionByJob():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    titles = {0:"Good credit Distribuition",1:"Good credit Distribuition"}
    df_dict = {0:df_good,1:df_bad}
    data = []
    for index in range(len(titles)):
        trace = go.Bar(x=df_dict[index]['Job'].value_counts().index.values,y=df_dict[index]['Job'].value_counts().values,name=titles[index])
        data.append(trace)
    layout = go.Layout(title="Job Distribuition")
    fig = go.Figure(data=data,layout=layout)
    py.iplot(fig,filename="grouped-bar")

# 2. Crossed by Credit amount
def getRiskDataCrossedByCreditAmount():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    titles = {0:"Good credit",1:"Bad credit"}
    df_dict = {0:df_good,1:df_bad}
    data = []
    for index in range(len(titles)):
        trace = go.Box(x=df_dict[index]['Job'],y=df_dict[index]['Credit amount'],name=titles[index])
        data.append(trace)
    layout = go.Layout(yaxis=dict(title="Credit Amount distribuition by Job"),boxmode='group')
    fig = go.Figure(data=data,layout=layout)
    py.iplot(fig,filename="box-age-cat")

# 3. Crossed by Age
def getRiskDataCrossedByAge():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    fig = {
        "data":[
            {
                "type": 'violin',
                "x": df_good['Job'],
                "y": df_good['Age'],
                "legendgroup": 'Good Credit',
                "scalegroup": 'No',
                "name": 'Good Credit',
                "side": 'negative',
                "box": {
                    "visible": True
                },
                "meanline": {
                    "visible": True
                },
                "line": {
                    "color": 'blue'
                }
            },
            {
                "type": 'violin',
                "x": df_bad['Job'],
                "y": df_bad['Age'],
                "legendgroup": 'Bad Credit',
                "scalegroup": 'No',
                "name": 'Good Credit',
                "side": 'negative',
                "box": {
                    "visible": True
                },
                "meanline": {
                    "visible": True
                },
                "line": {
                    "color": 'blue'
                }
            }
        ],
        "layout":{"yaxis":{"zeroline":False},"violingap":0,"violinmode":"overlay"},
    }
    py.iplot(fig,filename="Age-Housing",validate=False)

# 查看Credit Amont的分布
def getRiskDataOfCreditAmont():
    df = read_file()
    # 设置柱状图  大小
    fig,ax = plt.subplots(figsize=(12,12),nrows=2)
    fields = ['Credit amount','Age']
    titles = ["Credit Amount by Job","Job Type reference x Age"]
    xlabel = ['Job Reference','Job Reference']
    ylabel = ['Credit Amount','Age']
    for index in range(len(fields)):
        if index == 0:
            g = sns.boxplot(x="Job", y=fields[index], data=df,
                             palette="hls", ax=ax[0], hue="Risk")
        else:
            g = sns.violinplot(x="Job", y=fields[index], data=df, ax=ax[1],
               hue="Risk", split=True, palette="hls")
        g.set_title(titles[index], fontsize=15)
        g.set_xlabel(xlabel[index], fontsize=12)
        g.set_ylabel(ylabel[index], fontsize=12)

    plt.subplots_adjust(hspace=0.4, top=0.9)
    plt.show()


# 查看Credit Amont的分布
def getCreditAmountDistribuition():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    # Add histogram data
    x1 = np.log(df_good['Credit amount'])
    x2 = np.log(df_bad['Credit amount'])
    # Group data together
    his_data = [x1,x2]
    group_label = ['Good Credit','Bad Credit']
    # Create distplot with custom bin_size
    fig = ff.create_distplot(his_data,group_label,bin_size=2)
    #plot
    py.iplot(fig,filename="Distplot with Multiple Datasets")

#Ploting the good and bad dataframes in distplot
def showRiskData():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    # 设置 大小
    plt.figure(figsize = (8,5))
    g = sns.distplot(df_good['Credit amount'],color='r')
    g = sns.distplot(df_bad['Credit amount'],color='g')
    g.set_title("Credit Amount Frequency distribuition",fontsize=15)
    plt.show()

# 按风险分配储蓄账户
def getCreditAccountByRisk():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']

    df_dict = {0:df_good,1:df_bad}
    titles = {0:"Good credit",1:"Bad credit"}
    data = []
    fig = tools.make_subplots(rows=2, cols=2, specs=[[{}, {}], [{'colspan': 2}, None]],
                              subplot_titles=('Count Saving Accounts', 'Credit Amount by Savings Acc',
                                              'Age by Saving accounts'))
    for index in range(len(titles)):

        df_data = go.Bar(x=df_dict[index]['Saving accounts'].value_counts().index.values,
                         y=df_dict[index]['Saving accounts'].value_counts().values, name=titles[index])
        box = go.Box(x=df_dict[index]["Saving accounts"],y=df_dict[index]["Credit amount"],name=titles[index])
        scat = go.Box(x=df_dict[index]["Saving accounts"],y=df_dict[index]["Age"],name=titles[index])
        data.append(df_data)
        data.append(box)
        data.append(scat)
        fig.append_trace(df_data, 1, 1)
        fig.append_trace(box, 1, 2)
        fig.append_trace(scat, 2, 1)

    fig['layout'].update(height=700, width=800, title='Saving Accounts Exploration', boxmode='group')
    py.iplot(fig, filename='combined-savings')

# 如何更好地配置图例？我正在尝试替换下图，那么如何在 plotly 的子图上使用 violinplot？
def getSavingAccountsCount():
    df = read_file()
    titles = {0:"Saving Accounts Count",1:"Saving Accounts by Job",2:"Saving Accounts by Credit Amount"}
    ylabel = ["Count","Job","Credit amount"]
    # 绘制 图形 大小
    fig,ax = plt.subplots(3,1,figsize=(16,9))
    for index in range(len(titles)):
        # 设置 大小
        if index == 0:
            g = sns.countplot(x="Saving accounts",data=df,palette="hls",ax=ax[0],hue="Risk")
        elif index == 1:
            g = sns.violinplot(x="Saving accounts",y=ylabel[index],data = df,palette="hls",ax=ax[1],hue="Risk")
        else:
            g = sns.boxplot(x="Saving accounts", y=ylabel[index], data=df, ax=ax[2],
                            hue="Risk", palette="hls")
        g.set_title(titles[index], fontsize=15)
        g.set_ylabel(ylabel[index], fontsize=12)
    g.set_xlabel("Saving Accounts type", fontsize=12)
    plt.subplots_adjust(hspace=0.4, top=0.9)
    plt.show()

# 目标帐户按年龄计数分布.
def getPurposesAccountsCountByAge():
    df = read_file()
    titles = ["Purposes Count", "Purposes by Age", "Credit Amount distribuition by Purposes"]
    sub = [221,222,212]
    fields = ["Age",'Credit amount']
    # 设置 大小
    plt.figure(figsize=(14,12))
    for index in range(len(titles)):
        plt.subplot(sub[index])
        if index == 0:
            g = sns.countplot(x="Purpose",data=df,palette="hls", hue = "Risk")
        elif index == 1:
            g = sns.violinplot(x="Purpose", y=fields[index - 1], data=df,
                                palette="hls", hue="Risk", split=True)
        else:
            g = sns.boxplot(x="Purpose", y=fields[index - 1], data=df,
                             palette="hls", hue="Risk")
        g.set_xticklabels(g.get_xticklabels(),rotation=45)
        g.set_xlabel("", fontsize=12)
        g.set_ylabel("Count", fontsize=12)
        g.set_title(titles[index], fontsize=20)

    plt.subplots_adjust(hspace=0.6, top=0.8)
    plt.show()

# 贷款期限分布和密度
def getLoansDistribuition():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    # 设置 绘图 大小
    titles = ["Duration Count","Credit Amount distribuition by Duration","Duration Frequency x good and bad Credit"]
    fields = ["Credit amount"]
    xlabels = ["Duration Distribuition","Duration","Duration"]
    ylabels = ["Count","Credit Amount(US)","Frequency"]
    for index in range(len(titles)):
        plt.figure(figsize=(16,9))
        if index == 0:
            g = sns.countplot(x="Duration", data=df,
                              palette="hls", hue="Risk")
        elif index == 1:
            g = sns.pointplot(x="Duration",y=fields[index - 1],data=df,hue="Risk",palette="hls")
        else:
            g = sns.distplot(df_good['Duration'],color='g')
            g = sns.distplot(df_bad['Duration'],color='r')
        g.set_xlabel(xlabels[index], fontsize=12)
        g.set_ylabel(ylabels[index], fontsize=12)
        g.set_title(titles[index], fontsize=20)
        plt.subplots_adjust(wspace=0.4, hspace=0.4, top=0.9)
        plt.show()

# 检查帐户变量
def getRiskDataCheckAccount():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    titles = ["Good credit Distribuition","Bad credit Distribuition"]
    df_dict = [df_good,df_bad]
    data = []
    for index in range(len(titles)):
        trace = go.Bar(x=df_dict[index]['Checking account'].value_counts().index.values,
                       y=df_dict[index]['Checking account'].value_counts().values,name=titles[index])
        data.append(trace)
    layout = go.Layout(title = 'Checking accounts Distribuition',xaxis=dict(title="Checking accounts name"),yaxis=dict(title="Count"),barmode="group")
    fig = go.Figure(data=data,layout=layout)
    py.iplot(fig,filename="Age-ba",validate=False)

# Now, we will verify the values through Checking Accounts
def getVerifyDataCheckAccount():
    df = read_file()
    df_good = df[df['Risk'] == 'good']
    df_bad = df[df['Risk'] == 'bad']
    titles = ["Good credit","Bad credit"]
    df_dict = [df_good,df_bad]
    data = []
    for index in range(len(titles)):
        trace = go.Box(x=df_dict[index]['Checking account'],y=df_dict[index]['Credit amount'],name=titles[index],marker=dict(color= "#3D9970" if index == 0 else "#FF4136" ))
        data.append(trace)
    layout = go.Layout(yaxis=dict(title="Cheking distribuition"),barmode="group")
    fig = go.Figure(data=data,layout=layout)
    py.iplot(fig,filename="box-age-cat")

#  试图用交互式情节代替的旧情节
def getDataByCheckingAccount():
    df = read_file()
    titles = ["Checking Account Counting by Risk","Age by Checking Account","Credit Amount by Cheking Account"]
    # 设置 绘图 大小
    sub = [221,222,212]
    fields = ["Age","Credit amount"]
    plt.figure(figsize=(16,10))
    for index in range(len(titles)):
        # 设置 位置
        plt.subplot(sub[index])
        if index == 0:
           g = sns.countplot(x="Checking account",data=df,palette="hls",hue="Risk")
        elif index == 1:
           g = sns.violinplot(x='Checking account',y=fields[index - 1],data=df,palette="hls", hue = "Risk",split=True)
        else:
           g = sns.boxplot(x='Checking account',y=fields[index - 1],data=df,palette="hls")
        g.set_xlabel("Checking Account", fontsize=12)
        g.set_ylabel("Count", fontsize=12)
        g.set_title(titles[index], fontsize=20)
    plt.subplots_adjust(wspace=0.2, hspace=0.3, top=0.9)
    plt.show()


# 交叉表会话和其他人通过另一个稍微深入的指标来探索我们的数据
def getHousingByJob():
    df = read_file()
    # 设置大小
    plt.figure(figsize=(16,9))
    g = sns.violinplot(x="Housing",y="Job",data=df,hue="Risk",palette="hls",split=True)
    g.set_xlabel("Housing", fontsize=12)
    g.set_ylabel("Job", fontsize=12)
    g.set_title("Housing x Job - Dist", fontsize=20)
    plt.show()


def data_clean():
    filepath = "../file/german_credit_data-1.csv"
    df = pd.read_csv(filepath)
    print("Purpose : ", df.Purpose.unique())
    print("Sex : ", df.Sex.unique())
    print("Housing : ", df.Housing.unique())
    print("Saving accounts : ", df['Saving accounts'].unique())
    print("Risk : ", df['Risk'].unique())
    print("Checking account : ", df['Checking account'].unique())

    # 将数据转换为虚拟变量
    df['Saving accounts'] = df['Saving accounts'].fillna("no_inf")
    df['Checking account'] = df['Checking account'].fillna("no_inf")
    # get_dummies  将分类变量转换为虚拟指标变量。
    # Purpose to Dummies 变量
    df_new = df.merge(pd.get_dummies(df.Purpose,drop_first=True,prefix="Purpose"),left_index=True,right_index=True)
    print(df_new.head())
    # Sex feature in dummies
    df_new = df.merge(pd.get_dummies(df.Sex,drop_first=True,prefix="Sex"),left_index=True,right_index=True)
    print(df_new.head())
    df = df.merge(pd.get_dummies(df.Housing, drop_first=True, prefix='Housing'), left_index=True,
                                right_index=True)
    # Housing get Saving Accounts
    df = df.merge(pd.get_dummies(df["Saving accounts"], drop_first=True, prefix='Savings'),
                                left_index=True, right_index=True)
    # Housing get Risk
    df = df.merge(pd.get_dummies(df.Risk, prefix='Risk'), left_index=True, right_index=True)
    # Housing get Checking Account
    df = df.merge(pd.get_dummies(df["Checking account"], drop_first=True, prefix='Check'),
                                left_index=True, right_index=True)
    # Housing get Age categorical
    df = df.merge(pd.get_dummies(df["Age_cat"], drop_first=True, prefix='Age_cat'),
                                left_index=True, right_index=True)
    # Excluding the missing columns
    del df["Saving accounts"]
    del df["Checking account"]
    del df["Purpose"]

# Looking the correlation of the data
def getDataCorrelation():
    df = read_file()
    plt.figure(figsize=(14, 12))
    sns.heatmap(df.astype(float).corr(), linewidths=0.1, vmax=1.0,
                square=True, linecolor='white', annot=True)
    plt.show()











if __name__ == "__main__":
    # data_clean()
    # getDataByRisk()
    # getTargetVariableDistribution()
    # getHouseByRisk()
    # getCreditAmountByHousing()
    # getRiskDataBySex()
    # getRiskDataDistribuitionByJob()
    # getRiskDataCrossedByCreditAmount()
    # getRiskDataCrossedByAge()
    # getRiskDataOfCreditAmont()
    # getCreditAmountDistribuition()
    # showRiskData()

    # getCreditAccountByRisk()
    # getSavingAccountsCount()
    # getPurposesAccountsCountByAge()
    # getLoansDistribuition()

    # getRiskDataCheckAccount()
    # getVerifyDataCheckAccount()
    # getDataByCheckingAccount()
    # getHousingByJob()
    # data_clean()

    getDataCorrelation()